HAL SPDIFRX Typical use cases for migration ¶
This section provides information about the HAL SPDIFRX Typical use cases for migration.
The HAL SPDIFRX receive data and receive control APIs are almost the same between HAL1 and HAL2. The only differences are:
The naming changes are as follows: HAL1 uses
HAL_SPDIFRX_ReceiveDataFlow()andHAL_SPDIFRX_ReceiveCtrlFlow()(also available asHAL_SPDIFRX_ReceiveControlFlow()in some series), while HAL2 usesHAL_SPDIFRX_ReceiveData()andHAL_SPDIFRX_ReceiveCtrl(), respectively.The data buffer is now passed as a pointer to
voidinstead of a pointer to a specific data type. This allows the user to pass any data type without needing to cast at the application level.The processes for receiving data and control using polling, interrupts or DMA are the same in HAL1 and HAL2.
Use case: HAL SPDIFRX receptions in polling mode ¶
Sequence diagram ¶
|
HAL1 |
HAL2 |
|---|---|
|
SPDIFRX receptions in polling mode
|
SPDIFRX receptions in polling mode
|
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
#define SPDIFRX_DATA_SIZE 384
#define SPDIFRX_CTRL_SIZE 24
uint32_t SpdifRxDataBuffer[SPDIFRX_DATA_SIZE];
uint32_t SpdifRxCtrlBuffer[SPDIFRX_CTRL_SIZE];
SPDIFRX_HandleTypeDef hSPDIFRX1;
/* Enable the SPDIFRX clock and configure its
clock source using the HAL RCC driver
*/
hSPDIFRX1.Instance = SPDIFRX;
hSPDIFRX1.Init.InputSelection = SPDIFRX_INPUT_IN0;
hSPDIFRX1.Init.DataFormat = SPDIFRX_DATAFORMAT_MSB;
hSPDIFRX1.Init.PreambleTypeMask = SPDIFRX_PREAMBLETYPEMASK_ON;
hSPDIFRX1.Init.ChannelStatusMask = SPDIFRX_CHANNELSTATUS_ON;
hSPDIFRX1.Init.ValidityBitMask = SPDIFRX_VALIDITYMASK_OFF;
hSPDIFRX1.Init.ParityErrorMask = SPDIFRX_PARITYERRORMASK_OFF;
hSPDIFRX1.Init.Retries = SPDIFRX_MAXRETRIES_15;
hSPDIFRX1.Init.ChannelSelection = SPDIFRX_CHANNEL_A;
hSPDIFRX1.Init.StereoMode = SPDIFRX_STEREOMODE_ENABLE;
hSPDIFRX1.Init.WaitForActivity = SPDIFRX_WAITFORACTIVITY_ON;
hSPDIFRX1.Init.SymbolClockGen = ENABLE;
hSPDIFRX1.Init.BackupSymbolClockGen = ENABLE;
HAL_SPDIFRX_Init(&hSPDIFRX1);
/* Ensure that GPIO of SPDIFRX is
configured properly
/*
...
*/
/* Receive data */
if (HAL_SPDIFRX_ReceiveDataFlow(&hSPDIFRX1,
(uint32_t *)SpdifRxDataBuffer,
SPDIFRX_DATA_SIZE,
1000) != HAL_OK)
/* Receive control */
if (HAL_SPDIFRX_ReceiveCtrlFlow(&hSPDIFRX1,
(uint32_t *)SpdifRxCtrlBuffer,
SPDIFRX_CTRL_SIZE,
1000) != HAL_OK)
|
#define SPDIFRX_DATA_SIZE 384
#define SPDIFRX_CTRL_SIZE 24
uint32_t SpdifRxDataBuffer[SPDIFRX_DATA_SIZE];
uint32_t SpdifRxCtrlBuffer[SPDIFRX_CTRL_SIZE];
hal_spdifrx_config_t spdifrx_config;
hal_spdifrx_masks_t spdifrx_mask;
hal_spdifrx_handle_t hSPDIFRX1;
/* Enable the SPDIFRX clock and configure its
clock source using the HAL RCC driver
*/
HAL_SPDIFRX_Init(&hSPDIFRX1, HAL_SPDIFRX1);
spdifrx_config.input_selection = HAL_SPDIFRX_INPUT_0;
spdifrx_config.data_format = HAL_SPDIFRX_DATA_FORMAT_MSB;
HAL_SPDIFRX_SetConfig(&hSPDIFRX1,&spdifrx_config);
/* Additional optional configuration
feature when needed
*/
spdifrx_mask.preamble_mask = HAL_SPDIFRX_PREAMBLE_MASK_ENABLE;
spdifrx_mask.channel_user_mask = HAL_SPDIFRX_CHANNEL_USER_MASK_ENABLE;
spdifrx_mask.validity_mask = HAL_SPDIFRX_VALIDITY_MASK_DISABLE;
spdifrx_mask.parity_error_mask = HAL_SPDIFRX_PARITY_ERROR_MASK_DISABLE;
HAL_SPDIFRX_SetMasks(&hSPDIFRX1,&spdifrx_mask);
HAL_SPDIFRX_SetSynchroRetries(&hSPDIFRX1,HAL_SPDIFRX_SYNCHRO_RETRIES_15);
HAL_SPDIFRX_SetControlChannel(&hSPDIFRX1,HAL_SPDIFRX_CONTROL_CHANNEL_A);
HAL_SPDIFRX_EnableAlignmentForStereoOverrun(&hSPDIFRX1);
HAL_SPDIFRX_EnableWaitForActivity(&hSPDIFRX1);
HAL_SPDIFRX_EnableSymbolClock(&hSPDIFRX1,HAL_SPDIFRX_BACKUP_SYMBOL_CLK_ENABLED);
/* Ensure that GPIO of SPDIFRX is
configured properly
/*
...
*/
/* Receive data */
if (HAL_SPDIFRX_ReceiveData(&hSPDIFRX1,
(uint32_t *)SpdifRxDataBuffer,
SPDIFRX_DATA_SIZE,
1000) != HAL_OK)
/* Receive control */
if (HAL_SPDIFRX_ReceiveCtrl(&hSPDIFRX1,
(uint32_t *)SpdifRxCtrlBuffer,
SPDIFRX_CTRL_SIZE,
1000) != HAL_OK)
|
Use case: HAL SPDIFRX receptions in interrupt mode ¶
Note
The following sequence diagrams describe the processing APIs in interrupt mode. The configuration part has already been described in the polling use case above.
Sequence diagram ¶
|
HAL1 |
HAL2 |
|---|---|
|
SPDIFRX HAL Receive IT
|
SPDIFRX HAL Receive IT
|
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
#define SPDIFRX_DATA_SIZE 384
#define SPDIFRX_CTRL_SIZE 24
uint32_t SpdifRxBuffer[SPDIFRX_DATA_SIZE];
uint32_t SpdifCxBuffer[SPDIFRX_CTRL_SIZE];
SPDIFRX_HandleTypeDef hSPDIFRX1;
/* Ensure that all required peripherals
(SPDIFRX1, GPIO, etc.) are configured properly
/*
...
*/
/* Peripheral interrupt init */
/* Start data and control reception in interruption mode */
HAL_SPDIFRX_ReceiveDataFlow_IT(&hSPDIFRX1,
(uint32_t *) SpdifRxBuffer,
SPDIFRX_DATA_SIZE);
HAL_SPDIFRX_ReceiveCtrlFlow_IT(&hSPDIFRX1,
(uint32_t *) SpdifCxBuffer,
SPDIFRX_CTRL_SIZE);
/* Ensure that HAL_SPDIFRX_IRQHandler() is called for the appropriate SPDIFRX
instance within the corresponding ISR handlers according to the product.
*/
/* SPDIFRX1 data complete callback */
void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hSPDIFRX1)
{
data_cpt_occurred = 1;
}
/* SPDIFRX1 control complete callback */
void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hSPDIFRX1)
{
ctrl_cpt_occurred = 1;
}
|
#define SPDIFRX_DATA_SIZE 384
#define SPDIFRX_CTRL_SIZE 24
uint32_t SpdifRxBuffer[SPDIFRX_DATA_SIZE];
uint32_t SpdifCxBuffer[SPDIFRX_CTRL_SIZE];
hal_spdifrx_handle_t hSPDIFRX1;
/* Ensure that all required peripherals
(SPDIFRX1, GPIO etc.) are configured properly
/*
...
*/
/* Enable the SPDIFRX event interrupt
using the HAL CORTEX driver */
/* Start data and control reception in interruption mode */
HAL_SPDIFRX_ReceiveData_IT(&hSPDIFRX1,
(uint32_t *) SpdifRxBuffer,
SPDIFRX_DATA_SIZE);
HAL_SPDIFRX_ReceiveCtrl_IT(&hSPDIFRX1,
(uint32_t *) SpdifCxBuffer,
SPDIFRX_CTRL_SIZE);
/* Ensure that HAL_SPDIFRX_IRQHandler() is called for the required instance
within the corresponding ISR handlers according to the product.
*/
/* SPDIFRX1 data complete callback */
void HAL_SPDIFRX_DataCpltCallback(hal_spdifrx_handle_t *hSPDIFRX1)
{
data_cpt_occurred = 1;
}
/* SPDIFRX1 control complete callback */
void HAL_SPDIFRX_ControlCpltCallback(hal_spdifrx_handle_t *hSPDIFRX1)
{
ctrl_cpt_occurred = 1;
}
|
Use case: HAL SPDIFRX data flow reception in DMA mode ¶
Note
The following sequence diagrams describe the processing APIs for data reception in DMA mode. The configuration part has already been described in the polling use case above.
Sequence diagram ¶
SPDIFRX HAL Receive data DMA
SPDIFRX HAL Receive data DMA
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
#define SPDIFRX_DATA_SIZE 384
uint32_t SpdifRxBuffer[SPDIFRX_DATA_SIZE];
SPDIFRX_HandleTypeDef hSPDIFRX1;
DMA_NodeConfTypeDef NodeConfig;
DMA_NodeTypeDef Node_GPDMA1_Channel1;
DMA_QListTypeDef List_GPDMA1_Channel1;
DMA_HandleTypeDef handle_GPDMA1_Channel1;
volatile uint32_t data_cpt_occurred = 0U;
/* Ensure that all required peripherals
(SPDIFRX, GPIO, DMA Clock etc...) are configured properly
/*
...
*/
NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
NodeConfig.Init.Request = GPDMA1_REQUEST_SPDIF_RX_DT;
NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
NodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY;
NodeConfig.Init.SrcInc = DMA_SINC_FIXED;
NodeConfig.Init.DestInc = DMA_DINC_INCREMENTED;
NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
NodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
NodeConfig.Init.SrcBurstLength = 1;
NodeConfig.Init.DestBurstLength = 1;
NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
NodeConfig.Init.Mode = DMA_NORMAL;
NodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
NodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel1)
HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel1, NULL, &Node_GPDMA1_Channel1)
HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel1)
handle_GPDMA1_Channel1.Instance = GPDMA1_Channel1;
handle_GPDMA1_Channel1.InitLinkedList.Priority = DMA_HIGH_PRIORITY;
handle_GPDMA1_Channel1.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
handle_GPDMA1_Channel1.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT0;
handle_GPDMA1_Channel1.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_GPDMA1_Channel1.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
HAL_DMAEx_List_Init(&handle_GPDMA1_Channel1)
HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel1, &List_GPDMA1_Channel1)
__HAL_LINKDMA(hspdifrx, hdmaDrRx, handle_GPDMA1_Channel1);
/* Start data reception in DMA mode */
HAL_SPDIFRX_ReceiveDataFlow_DMA(&hSPDIFRX1,
(uint32_t *) SpdifRxBuffer,
SPDIFRX_DATA_SIZE);
/* Stop the audio stream receive */
HAL_SPDIFRX_DMAStop(&hSPDIFRX1);
/* Check the exact name of the SPDIFRX data
DMA IRQ handler in the device startup file. */
/* SPDIFRX data complete callback */
void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hSPDIFRX1)
{
data_cpt_occurred = 1;
}
|
#define SPDIFRX_DATA_SIZE 384
uint32_t SpdifRxBuffer[SPDIFRX_DATA_SIZE];
hal_spdifrx_handle_t hSPDIFRX1;
hal_dma_handle_t hGPDMA1_CH1;
hal_dma_node_t DMA_Node_SPDIFRX1_DT;
volatile uint32_t data_cpt_occurred = 0U;
/* Ensure that all required peripherals
(SPDIFRX, GPIO, NVIC, DMA Clock etc...) are configured properly
/*
...
*/
HAL_DMA_Init(&hGPDMA1_CH1, HAL_GPDMA1_CH1);
hal_dma_direct_xfer_config_t xfer_cfg_spdifrx1_dt_dma;
xfer_cfg_spdifrx1_dt_dma.request = HAL_GPDMA1_REQUEST_SPDIFRX1_DT;
xfer_cfg_spdifrx1_dt_dma.direction = HAL_DMA_DIRECTION_PERIPH_TO_MEMORY;
xfer_cfg_spdifrx1_dt_dma.src_inc = HAL_DMA_SRC_ADDR_FIXED;
xfer_cfg_spdifrx1_dt_dma.dest_inc = HAL_DMA_DEST_ADDR_INCREMENTED;
xfer_cfg_spdifrx1_dt_dma.src_data_width = HAL_DMA_SRC_DATA_WIDTH_WORD;
xfer_cfg_spdifrx1_dt_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_WORD;
xfer_cfg_spdifrx1_dt_dma.priority = HAL_DMA_PRIORITY_HIGH;
HAL_DMA_SetConfigPeriphLinkedListCircularXfer(&hGPDMA1_CH1, &DMA_Node_SPDIFRX1_DT, &xfer_cfg_spdifrx1_dt_dma);
HAL_DMA_SetLinkedListXferFetchNodePort(&hGPDMA1_CH1, HAL_DMA_PORT0);
/* Link the receive data DMA handle to the SPDIFRX handle */
HAL_SPDIFRX_SetDataDMA(&hSPDIFRX1, &hGPDMA1_CH1);
/* Start data reception in DMA mode */
HAL_SPDIFRX_ReceiveData_DMA(&hSPDIFRX1,
(uint32_t *) SpdifRxBuffer,
SPDIFRX_DATA_SIZE);
/* Abort the reception of data flow */
HAL_SPDIFRX_Data_Abort(&hSPDIFRX1);
/* Check the exact name of the SPDIFRX data
DMA IRQ handler in the device startup file. */
/* SPDIFRX data complete callback */
void HAL_SPDIFRX_DataCpltCallback(hal_spdifrx_handle_t *hSPDIFRX1)
{
data_cpt_occurred = 1;
}
|
Use case: HAL SPDIFRX control flow reception in DMA mode ¶
Note
The following sequence diagrams describe the processing APIs for control reception in DMA mode. The configuration part has already been described in the polling use case above.
Sequence diagram ¶
SPDIFRX HAL Receive control DMA
SPDIFRX HAL Receive control DMA
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
#define SPDIFRX_CTRL_SIZE 24
uint32_t SpdifCxBuffer[SPDIFRX_CTRL_SIZE];
SPDIFRX_HandleTypeDef hSPDIFRX1;
DMA_NodeConfTypeDef NodeConfig;
DMA_NodeTypeDef Node_GPDMA1_Channel0;
DMA_QListTypeDef List_GPDMA1_Channel0;
DMA_HandleTypeDef handle_GPDMA1_Channel0;
volatile uint32_t ctrl_cpt_occurred = 0U;
/* Ensure that all required peripherals
(SPDIFRX, GPIO, NVIC, DMA Clock etc...) are configured properly
/*
...
*/
NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
NodeConfig.Init.Request = GPDMA1_REQUEST_SPDIF_RX_CS;
NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
NodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY;
NodeConfig.Init.SrcInc = DMA_SINC_FIXED;
NodeConfig.Init.DestInc = DMA_DINC_INCREMENTED;
NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;
NodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
NodeConfig.Init.SrcBurstLength = 1;
NodeConfig.Init.DestBurstLength = 1;
NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT1;
NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
NodeConfig.Init.Mode = DMA_NORMAL;
NodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
NodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel0)
HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel0, NULL, &Node_GPDMA1_Channel0)
HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel0)
handle_GPDMA1_Channel0.Instance = GPDMA1_Channel0;
handle_GPDMA1_Channel0.InitLinkedList.Priority = DMA_HIGH_PRIORITY;
handle_GPDMA1_Channel0.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
handle_GPDMA1_Channel0.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT0;
handle_GPDMA1_Channel0.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
handle_GPDMA1_Channel0.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
HAL_DMAEx_List_Init(&handle_GPDMA1_Channel0)
HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel0, &List_GPDMA1_Channel0)
__HAL_LINKDMA(hSPDIFRX1, hdmaCsRx, handle_GPDMA1_Channel0);
/* Start control reception in DMA mode */
HAL_SPDIFRX_ReceiveCtrlFlow_DMA(&hSPDIFRX1,
(uint32_t *) SpdifCxBuffer,
SPDIFRX_CTRL_SIZE);
/* Stop the audio stream receive */
HAL_SPDIFRX_DMAStop(&hSPDIFRX1);
/* Check the exact name of the SPDIFRX control
DMA IRQ handler in the device startup file. */
/* SPDIFRX control complete callback */
void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hSPDIFRX1)
{
ctrl_cpt_occurred = 1;
}
|
#define SPDIFRX_CTRL_SIZE 24
uint32_t SpdifCxBuffer[SPDIFRX_CTRL_SIZE];
hal_spdifrx_handle_t hSPDIFRX1;
hal_dma_handle_t hGPDMA1_CH0;
hal_dma_node_t DMA_Node_SPDIFRX1_CS;
volatile uint32_t control_cpt_occurred = 0U;
/* Ensure that all required peripherals
(SPDIFRX, GPIO, NVIC, DMA Clock etc...) are configured properly
/*
...
*/
HAL_DMA_Init(&hGPDMA1_CH0, HAL_GPDMA1_CH0);
hal_dma_direct_xfer_config_t xfer_cfg_spdifrx1_cs_dma;
xfer_cfg_spdifrx1_cs_dma.request = HAL_GPDMA1_REQUEST_SPDIFRX1_CS;
xfer_cfg_spdifrx1_cs_dma.direction = HAL_DMA_DIRECTION_PERIPH_TO_MEMORY;
xfer_cfg_spdifrx1_cs_dma.src_inc = HAL_DMA_SRC_ADDR_FIXED;
xfer_cfg_spdifrx1_cs_dma.dest_inc = HAL_DMA_DEST_ADDR_INCREMENTED;
xfer_cfg_spdifrx1_cs_dma.src_data_width = HAL_DMA_SRC_DATA_WIDTH_WORD;
xfer_cfg_spdifrx1_cs_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_WORD;
xfer_cfg_spdifrx1_cs_dma.priority = HAL_DMA_PRIORITY_HIGH;
HAL_DMA_SetConfigPeriphLinkedListCircularXfer(&hGPDMA1_CH1, &DMA_Node_SPDIFRX1_CS, &xfer_cfg_spdifrx1_cs_dma)
HAL_DMA_SetLinkedListXferFetchNodePort(&hGPDMA1_CH1, HAL_DMA_PORT0)
/* Link the receive control DMA handle to the SPDIFRX handle */
HAL_SPDIFRX_SetControlDMA(&hSPDIFRX1, &hGPDMA1_CH0);
/* Start control reception in DMA mode */
HAL_SPDIFRX_ReceiveCtrl_DMA(&hSPDIFRX1,
(uint32_t *) SpdifCxBuffer,
SPDIFRX_CTRL_SIZE);
/* Abort the reception of control flow */
HAL_SPDIFRX_Ctrl_Abort(&hSPDIFRX1);
/* Check the exact name of the SPDIFRX control
DMA IRQ handler in the device startup file. */
/* SPDIFRX control complete callback */
void HAL_SPDIFRX_ControlCpltCallback(hal_spdifrx_handle_t *hSPDIFRX1)
{
control_cpt_occurred = 1;
}
|